package dk.snaveponyklub.persist.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;

import dk.snaveponyklub.handler.impl.HandlerImpl;
import dk.snaveponyklub.util.Logger;


public class PersonCacheImpl {

    Namespace ns = Namespace.getNamespace("s", "http://www.snaveponyklub.dk");
    Namespace xsi = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    XMLLoaderImpl loader = new XMLLoaderImpl();
    XMLValidator validator = new XMLValidator();
    Document persons;
	
	public PersonCacheImpl()
	{
		refreshCache();
	}
	
	private void refreshCache() {
		persons = loader.loadPersonsDocument();
	}

    public void addPerson(String xml) throws Throwable {
    	try {
    		if (validator.isValid(xml, "Persist.xsd")) {
            	Document document = loader.loadXml(xml);
            	XPath xp = XPath.newInstance("//s:persons/s:person");
                xp.addNamespace(ns);
                Element person = (Element)xp.selectSingleNode(document);
                String username = person.getChildText("username", ns); 
                if (!userAlreadyFound(username))
                {
                    person.setAttribute("id", getNextId());

                	xp = XPath.newInstance("//s:persons");
                	xp.addNamespace(ns);
        			Element personsElement = (Element)xp.selectSingleNode(persons);            
                    
                    personsElement.addContent((Element)person.clone());
                    loader.writePersons(persons);
                    refreshCache();
                } else {
        			throw new Throwable("Bruger findes allerede");
                }
    		} else { 
    			throw new Throwable("Not valid person");
    		}
    		
        } catch (JDOMException e) {
            e.printStackTrace();
		}
    }
	
    public Element getPerson(int id) {
        try {
            XPath xp = XPath.newInstance("//s:person[@id='" + id + "']");
            xp.addNamespace(ns);
            Element person = (Element)xp.selectSingleNode(persons);
            return person;
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean userAlreadyFound(String username) {
        try {
            XPath xp = XPath.newInstance("//s:person[s:username='" + username + "']");
            xp.addNamespace(ns);
            Element person = (Element)xp.selectSingleNode(persons);
            return person != null;
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return false;
    }
   
    public String checkPassword(String username, String password) throws Throwable {
        try {
            XPath xp = XPath.newInstance("//s:person[s:username='" + username + "' and s:password='" + password + "']");
            xp.addNamespace(ns);
            Element person = (Element)xp.selectSingleNode(persons);
            if (person != null) {
            	Document document = new Document(new Element("userlogin", ns));
            	person.getChild("password", ns).setText("");
            	document.getRootElement().addContent((Element)person.clone());
                return extractXML(document);
            } else {
            	throw new Throwable("Bruger findes ikke");
            }
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return null;
    }

	public String extractXML(Document document) {
		String xml = null;
		XMLOutputter xo = new XMLOutputter();
        Format format = Format.getPrettyFormat();
        format.setEncoding("UTF-8");
        xo.setFormat(format);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            xo.output(document, baos);
            xml = baos.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return xml;
	}
    
    public Element getPersons() {
        try {
            XPath xp = XPath.newInstance("//s:persons");
            xp.addNamespace(ns);
            Element personsElement = (Element)xp.selectSingleNode(persons);
            return personsElement;
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getNextId() {
    	int maxId = 1;
        try {
            XPath xp = XPath.newInstance("//s:persons/s:person");
            xp.addNamespace(ns);
            @SuppressWarnings("unchecked")
			List<Element> personElements = xp.selectNodes(persons);

            for (Element element : personElements) {
                try {
                    int id = Integer.parseInt(element.getAttributeValue("id"));
                    if (id > maxId) {
                    	maxId = id;
                    }
                } catch (NumberFormatException e) {
                    Logger.error("Error get id from person");
                }
			}
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return (maxId+1)+"";
    }
    
    
	public static void main(String[] args) throws IOException, Throwable {
		PersonCacheImpl cache = new PersonCacheImpl();
    	//Element person = cache.getPerson(2);
//    	Element person = cache.getPersons();
//        XMLOutputter xo = new XMLOutputter();
//        xo.output(person, System.out);

//	    Namespace ns = Namespace.getNamespace("s", "http://www.snaveponyklub.dk");
//	    Namespace xsi = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");    	Document person = new Document();
//        Element persist = new Element("persist", ns);
//        Element persons = new Element("persons", ns);
//        persist.addContent(persons);
//        Element student = new Element("person", ns);
//        student.addNamespaceDeclaration(xsi);
//        student.setAttribute("type", "s:studenttype", xsi);
//        student.setAttribute("id", "9");
//        student.addContent(new Element("name", ns).setText("Niels"));
//        student.addContent(new Element("lastname", ns).setText("Ole"));
//        student.addContent(new Element("username", ns).setText("OO"));
//        student.addContent(new Element("password", ns).setText("pass"));
//        persons.addContent(student);
//        person.setRootElement(persist);
//       
//        String personXml = new HandlerImpl().extractXML(person);
//        System.out.println("Xml: " + personXml);
//        cache.addPerson(personXml);
//        
//        Document document = new XMLLoaderImpl().loadPersonsDocument();
//        String xml = new HandlerImpl().extractXML(document);
//        System.out.println("Xml: " + xml);
        
    	Element persons = cache.getPersons();
        XMLOutputter xo = new XMLOutputter();
        xo.output(persons, System.out);
        
        System.out.println(cache.checkPassword("JOP", "zpass"));
	}

}
